#include "PthPadCalculator.h"

PthPadCalculator::PthPadCalculator(QObject *parent):
    QObject(parent)
{
    clear();
}

PthPadCalculator::~PthPadCalculator()
{

}

bool PthPadCalculator::calculate()
{
    setHoleDiameter(leadThicknessMax() + holeOverLead());
    const qreal padCalculated = roundTo(holeDiameter() * padToHoleRatio(), roundOff());
    const qreal padMin = holeDiameter() + 2.0 * minimalAnularRing();
    setRegularPadDiameter(qMax(padCalculated, padMin));
    const qreal id = holeDiameter() + thermalIdOverHole();
    setThermalPadInnderDiameter(roundTo(id, roundOff()));
    const qreal od = thermalIdOverHole() + minimalThermalOdOverId() + thermalOdToHoleRatio() * holeDiameter();
    setThermalPadOuterDiameter(roundTo(od, roundOff()));
    const qreal sw = 0.01 * spokeWidthToQuarterOdPercent() * thermalPadOuterDiameter() / 4.0;
    setThermalPadSpokeWidth(roundTo(sw, 0.01));
    setAntiPadDiameter(thermalPadOuterDiameter());

    return true;
}

qreal PthPadCalculator::leadThicknessMax() const
{
    return m_leadThicknessMax;
}

qreal PthPadCalculator::holeOverLead() const
{
    return m_holeOverLead;
}

qreal PthPadCalculator::padToHoleRatio() const
{
    return m_padToHoleRatio;
}

qreal PthPadCalculator::minimalAnularRing() const
{
    return m_minimalAnularRing;
}

qreal PthPadCalculator::thermalIdOverHole() const
{
    return m_thermalIdOverHole;
}

qreal PthPadCalculator::minimalThermalOdOverId() const
{
    return m_minimalThermalOdOverId;
}

qreal PthPadCalculator::thermalOdToHoleRatio() const
{
    return m_thermalOdToHoleRatio;
}

qreal PthPadCalculator::spokeWidthToQuarterOdPercent() const
{
    return m_spokeWidthToQuarterOdPercent;
}

qreal PthPadCalculator::roundOff() const
{
    return m_roundOff;
}

qreal PthPadCalculator::holeDiameter() const
{
    return m_holeDiameter;
}

qreal PthPadCalculator::regularPadDiameter() const
{
    return m_regularPadDiameter;
}

qreal PthPadCalculator::thermalPadInnderDiameter() const
{
    return m_thermalPadInnderDiameter;
}

qreal PthPadCalculator::thermalPadOuterDiameter() const
{
    return m_thermalPadOuterDiameter;
}

qreal PthPadCalculator::thermalPadSpokeWidth() const
{
    return m_thermalPadSpokeWidth;
}

qreal PthPadCalculator::antiPadDiameter() const
{
    return m_antiPadDiameter;
}

void PthPadCalculator::setLeadThicknessMax(qreal leadThicknessMax)
{
    if (qFuzzyCompare(m_leadThicknessMax, leadThicknessMax))
        return;

    m_leadThicknessMax = leadThicknessMax;
    emit leadThicknessMaxChanged(leadThicknessMax);
}

void PthPadCalculator::setHoleOverLead(qreal holeOverLead)
{
    if (qFuzzyCompare(m_holeOverLead, holeOverLead))
        return;

    m_holeOverLead = holeOverLead;
    emit holeOverLeadChanged(holeOverLead);
}

void PthPadCalculator::setPadToHoleRatio(qreal padToHoleRatio)
{
    if (qFuzzyCompare(m_padToHoleRatio, padToHoleRatio))
        return;

    m_padToHoleRatio = padToHoleRatio;
    emit padToHoleRatioChanged(padToHoleRatio);
}

void PthPadCalculator::setMinimalAnularRing(qreal minimalAnularRing)
{
    if (qFuzzyCompare(m_minimalAnularRing, minimalAnularRing))
        return;

    m_minimalAnularRing = minimalAnularRing;
    emit minimalAnularRingChanged(minimalAnularRing);
}

void PthPadCalculator::setThermalIdOverHole(qreal thermalIdOverHole)
{
    if (qFuzzyCompare(m_thermalIdOverHole, thermalIdOverHole))
        return;

    m_thermalIdOverHole = thermalIdOverHole;
    emit thermalIdOverHoleChanged(thermalIdOverHole);
}

void PthPadCalculator::setMinimalThermalOdOverId(qreal minimalThermalOdOverId)
{
    if (qFuzzyCompare(m_minimalThermalOdOverId, minimalThermalOdOverId))
        return;

    m_minimalThermalOdOverId = minimalThermalOdOverId;
    emit minimalThermalOdOverIdChanged(minimalThermalOdOverId);
}

void PthPadCalculator::setThermalOdToHoleRatio(qreal ThermalOdToHoleRatio)
{
    if (qFuzzyCompare(m_thermalOdToHoleRatio, ThermalOdToHoleRatio))
        return;

    m_thermalOdToHoleRatio = ThermalOdToHoleRatio;
    emit ThermalOdToHoleRatioChanged(ThermalOdToHoleRatio);
}

void PthPadCalculator::setSpokeWidthToQuarterOdPercent(qreal spokeWidthToQuarterOdPercent)
{
    if (qFuzzyCompare(m_spokeWidthToQuarterOdPercent, spokeWidthToQuarterOdPercent))
        return;

    m_spokeWidthToQuarterOdPercent = spokeWidthToQuarterOdPercent;
    emit spokeWidthToQuarterOdPercentChanged(spokeWidthToQuarterOdPercent);
}

void PthPadCalculator::setRoundOff(qreal roundOff)
{
    if (qFuzzyCompare(m_roundOff, roundOff))
        return;

    m_roundOff = roundOff;
    emit roundOffChanged(roundOff);
}

void PthPadCalculator::clear()
{
    setLeadThicknessMax(0.0);
    setHoleOverLead(0.0);
    setPadToHoleRatio(0.0);
    setMinimalAnularRing(0.0);
    setThermalIdOverHole(0.0);
    setMinimalThermalOdOverId(0.0);
    setThermalOdToHoleRatio(0.0);
    setSpokeWidthToQuarterOdPercent(0.0);
    setRoundOff(0.0);

    setHoleDiameter(0.0);
    setRegularPadDiameter(0.0);
    setThermalPadInnderDiameter(0.0);
    setThermalPadOuterDiameter(0.0);
    setThermalPadSpokeWidth(0.0);
    setAntiPadDiameter(0.0);
}

void PthPadCalculator::setHoleDiameter(qreal holeDiameter)
{
    if (qFuzzyCompare(m_holeDiameter, holeDiameter))
        return;

    m_holeDiameter = holeDiameter;
    emit holeDiameterChanged(holeDiameter);
}

void PthPadCalculator::setRegularPadDiameter(qreal regularPadDiameter)
{
    if (qFuzzyCompare(m_regularPadDiameter, regularPadDiameter))
        return;

    m_regularPadDiameter = regularPadDiameter;
    emit regularPadDiameterChanged(regularPadDiameter);
}

void PthPadCalculator::setThermalPadInnderDiameter(qreal thermalPadInnderDiameter)
{
    if (qFuzzyCompare(m_thermalPadInnderDiameter, thermalPadInnderDiameter))
        return;

    m_thermalPadInnderDiameter = thermalPadInnderDiameter;
    emit thermalPadInnderDiameterChanged(thermalPadInnderDiameter);
}

void PthPadCalculator::setThermalPadOuterDiameter(qreal thermalPadOuterDiameter)
{
    if (qFuzzyCompare(m_thermalPadOuterDiameter, thermalPadOuterDiameter))
        return;

    m_thermalPadOuterDiameter = thermalPadOuterDiameter;
    emit thermalPadOuterDiameterChanged(thermalPadOuterDiameter);
}

void PthPadCalculator::setThermalPadSpokeWidth(qreal thermalPadSpokeWidth)
{
    if (qFuzzyCompare(m_thermalPadSpokeWidth, thermalPadSpokeWidth))
        return;

    m_thermalPadSpokeWidth = thermalPadSpokeWidth;
    emit thermalPadSpokeWidthChanged(thermalPadSpokeWidth);
}

void PthPadCalculator::setAntiPadDiameter(qreal antiPadDiameter)
{
    if (qFuzzyCompare(m_antiPadDiameter, antiPadDiameter))
        return;

    m_antiPadDiameter = antiPadDiameter;
    emit antiPadDiameterChanged(antiPadDiameter);
}
